#ifndef YMODEM_H
#define YMODEM_H


#ifdef __cplusplus
 extern "C" {
#endif /* __cplusplus */

typedef enum {
  MBL_FLASH_ERASE_ERROR=-19,
  MBL_FLASH_WRITE_ERROR,
  MBL_YMODEM_ABORTED_ERROR,
  MBL_YMODEM_ABORTED_USER,
}MBL_ERROR;


/* /-------- Packet---------------------------------------------------------\
 * | 0      |  1    |  2     |  3   |  4      | ... | n+4     | n+5  | n+6  |
 * |------------------------------------------------------------------------|
 * | unused | start | number | !num | data[0] | ... | data[n] | crc0 | crc1 |
 * \------------------------------------------------------------------------/
 * the first byte is left unused for memory alignment reasons
 */
#define PACKET_SEQNO_INDEX      (1)
#define PACKET_SEQNO_COMP_INDEX (2)

#define PACKET_HEADER           (3)
#define PACKET_TRAILER          (2)
#define PACKET_OVERHEAD         (PACKET_HEADER + PACKET_TRAILER)
#define PACKET_SIZE             (128)
#define PACKET_1K_SIZE          (1024)

#define FILE_NAME_LENGTH        (256)
#define FILE_SIZE_LENGTH        (16)

#define SOH                     (0x01)  //128  byte
#define STX                     (0x02)  //1024 byte
#define EOT                     (0x04)  //end
#define ACK                     (0x06)  //respond
#define NAK                     (0x15)  //none respond
#define CA                      (0x18)  //
#define CRC16                   (0x43)  //'C' == 0x43, need 16-bit CRC

#define ABORT1                  (0x41)  //'A' == 0x41, user Abort
#define ABORT2                  (0x61)  //'a' == 0x61, user Abort


#define NAK_TIMEOUT             (0x3e8)
#define MAX_ERRORS              (5)


#define IS_AF(c)  ((c >= 'A') && (c <= 'F'))
#define IS_af(c)  ((c >= 'a') && (c <= 'f'))
#define IS_09(c)  ((c >= '0') && (c <= '9'))
#define ISVALIDHEX(c)  IS_AF(c) || IS_af(c) || IS_09(c)
#define ISVALIDDEC(c)  IS_09(c)
#define CONVERTDEC(c)  (c - '0')
#define CONVERTHEX_alpha(c)  (IS_AF(c) ? (c - 'A'+10) : (c - 'a'+10))
#define CONVERTHEX(c)   (IS_09(c) ? (c - '0') : CONVERTHEX_alpha(c))


#if defined(__CC_ARM) || defined(__CLANG_ARM)           /* ARM Compiler */
#define ALIGN(n)                    __attribute__((aligned(n)))
#elif defined (__IAR_SYSTEMS_ICC__)             /* for IAR Compiler */
#define ALIGN(n)                    PRAGMA(data_alignment=n)
#elif defined (__GNUC__)                /* GNU GCC Compiler */
#define ALIGN(n)                    __attribute__((aligned(n)))
#elif defined (__ADSPBLACKFIN__)        /* for VisualDSP++ Compiler */
#define ALIGN(n)                    __attribute__((aligned(n)))
#elif defined (_MSC_VER)
#define ALIGN(n)                    __declspec(align(n))
#elif defined (__TI_COMPILER_VERSION__)
#define ALIGN(n)
#else
    #error not supported tool chain
#endif

unsigned char ymodem_transmit(unsigned char *buf, const unsigned char *sendFileName, unsigned long sizeFile);

#ifdef __cplusplus
}
#endif /* __cplusplus */

#endif // YMODEM_H
